/**
 ******************************************************************************
 * @file	watchdog-simple.c
 * @brief	看门狗特性测试

 * 控制台输入
 ./watchdog-simple.elf -D /dev/watchdog -t 5 -e 3



 *
 * - 2016-9-30,MenglongWu,MenglongWoo@aliyun.com
*/





#include <linux/watchdog.h>

#include <sys/ioctl.h>

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#include "proginfo.h"
#include "autoconfig.h"

char *device = "/dev/watchdog";		// 默认设备
int timeout = 10;			// 看门狗超时
int exitsec = 5;			// 程序最长运行时长
int safe    = 1;			// 是否安全关闭，非安全情况下看门狗超时

static void print_usage(const char *prog)
{
	printf("Usage: %s [-DsbdlHOLC3]\n", prog);
	puts("  -D --device   device to use (default /dev/watchdog)\n"
	     "  -t --timeout  watchdog timeout (10 sec)\n"
	     "  -e --exit     after n secend exit (5 sec)\n"
	     "  -s --safe     safe close watchdog device (true)\n");
	exit(1);
}



static void parse_opts(int argc, char *argv[])
{
	while (1) {
		static const struct option lopts[] = {
			{ "device",  1, 0, 'D' },
			{ "timeout", 1, 0, 't' },
			{ "exit",    0, 0, 'e' },
			{ "safe",    0, 0, 's' },
			{ NULL, 0, 0, 0 },
		};
		int c;

		c = getopt_long(argc, argv, "D:t:e:s:", lopts, NULL);

		if (c == -1) {
			break;
		}

		switch (c) {
		case 'D':
			device = optarg;
			break;
		case 't':
			timeout = atoi(optarg);
			if (timeout < 1) {
				timeout = 1;
			}
			break;
		case 'e':
			exitsec = atoi(optarg);
			break;
		case 's':
			safe = optarg[0] == 'f' ? 0 : 1;
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}

int main(int argc, char *argv[])
{
	parse_opts(argc, argv);
	printf("device %s timeout %d exitsec %d safe %d\n",
	       device,
	       timeout,
	       exitsec,
	       safe);
	int fd = open("/dev/watchdog", O_WRONLY);
	int ret = 0;
	if (fd == -1) {
		perror("watchdog");
		exit(EXIT_FAILURE);
	}
	int tmp;
	struct watchdog_info winfo;

	ret = ioctl(fd, WDIOC_GETSUPPORT, &winfo);
	printf("WDIOC_GETSUPPORT support \n");
	if (winfo.options & WDIOF_CARDRESET) {
		printf("\tWDIOF_CARDRESET\n");
	}
	if (winfo.options & WDIOF_MAGICCLOSE) {
		printf("\tWDIOF_MAGICCLOSE\n");
	}
	if (winfo.options & WDIOF_SETTIMEOUT) {
		printf("\tWDIOF_SETTIMEOUT\n");
	}
	if (winfo.options & WDIOF_KEEPALIVEPING) {
		printf("\tWDIOF_KEEPALIVEPING\n");
	}
	printf("ID %s\n", winfo.identity );

	ret = ioctl(fd, WDIOC_GETTIMEOUT, &tmp);
	printf("\nWDIOC_GETTIMEOUT\t%d\n", tmp);


	ioctl(fd, WDIOC_SETTIMEOUT, &timeout);

	tmp = WDIOS_DISABLECARD;
	while (exitsec--) {
		// 向看门狗写入任意字符可复位看门狗
		ret = write(fd, "\0", 1);
		if (ret != 1) {
			ret = -1;
			break;
		}
		sleep(1);
	}

	// ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &tmp);
	// printf("ret = %d WDIOC_GETBOOTSTATUS %d\n", ret, tmp);
	// 直接close关闭看么狗并没有关闭硬件
	// 关闭硬件唯一防范是写入 V
	if (safe) {
		write(fd, "V", 1);
	}
	close(fd);
	return ret;
}


MODULE_PROJECT(PRJ_NAME);
MODULE_BUILD(__DATE__ " " __TIME__);
PROG_GITSHA1(__GIT_SHA1__);